package example.hello_security.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import example.hello_security.entity.Role;
import example.hello_security.entity.User;
import example.hello_security.entity.LoginsUserDetail;
import example.hello_security.mapper.RoleMapper;
import example.hello_security.mapper.RolePermissionMapper;
import example.hello_security.mapper.UserMapper;
import example.hello_security.mapper.UserPermissionMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserServiceImpl implements UserDetailsService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserPermissionMapper userPermissionMapper;


    /**
     * description 重写load方法，将登录时刻检测的信息根据DAO进行检测
     * @author zken
     * @param username 抽象为账号，返回一整个UserDetails，之后交给别的模块进行验证
     * CreateDate 2024/10/27 00:39:03
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 传入的参数是账户名称，建议需要改名处理，方便查看
        String phone = username;

        // 查询账户信息
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        User user = userMapper.selectOne(wrapper);
        LoginsUserDetail loginsUserDetail = new LoginsUserDetail(user);

        // 获取角色名称
        List<Role> roles = roleMapper.findRoleIdListByUserId(user.getId());
        List<Integer> roleIds = roles
                .stream()
                .map(Role::getId) // 假设 Role 类中有 getId() 方法
                .toList();
        List<String> roleNames = roles
                .stream()
                .map(Role::getName)
                .toList();
        // 获取角色对应的所有权限列表
        List<String> rolePermissionNameList = rolePermissionMapper.selectRolePermissionListByRoleId(roleIds);
        // 用户权限的集合
        Set<String> userPermissionNameSet = new HashSet<>(rolePermissionNameList);

        // 获取用户独有的权限列表
        List<String> userOnlyPermissionNameList = userPermissionMapper.selectPermissionByUserId(user.getId());
        userPermissionNameSet.addAll(userOnlyPermissionNameList);
        // 用户所拥有的所有权限的列表 -- 根据集合创建（目的：消除重复的权限名称）
        List<String> userPermissionNameList = new ArrayList<>(userPermissionNameSet);


        // 添加对应的权限内容
        loginsUserDetail.setPermissionNames(userPermissionNameList);
        loginsUserDetail.setRoleNames(roleNames);

        return loginsUserDetail;
    }

}
